#! /usr/bin/env python
# -*- coding: utf-8 -*- 
 
from wsgiref.simple_server import make_server
import urllib2
import time
import threading
import algorithm
import migration
import json

semaphore = threading.Semaphore(0)
lock = threading.Lock()
response_body = {"virtual_migration_list":[]}
movement_list_result = []
compute_shutdown_list_result = []

def dynamic_migration_algorithm():
    """运行动态自动迁移算法。
    
    运行动态迁移算法，在response_body中写入需要迁移的虚拟机列表，和需要关闭的主机列表。

    参数：
        无

    返回值：
        无
    """ 
    global semaphore   
    global lock
    global response_body
    global movement_list_result
    global compute_shutdown_list_result
    compute_noshutdown_list = []
    while True:
        #lock.acquire()
        #当信号量内的计数器为0时，该线程休眠，等待其它线程唤醒，否则将计数器减1。
        semaphore.acquire()
        algorithm.pretreat()
        hot_movement_list = algorithm.solve_hotspot()
        #(green_compute_movement_list, compute_shutdown_list) = algorithm.solve_green_computing()
        #movement_list = algorithm.consolidate_movement(hot_movement_list, green_compute_movement_list)
        '''
        for movement_virtual in movement_list:
            if movement_virtual["status"] == "ACTIVE":
                logo = migration.manual_migration(movement_virtual["id"], movement_virtual["destination"])
                if logo == True:
                    movement_list_result.append(movement_virtual)
            else:
                compute_noshutdown_list.append(movement_list["source"])
        for compute_shutdown in compute_shutdown_list:
            if compute_shutdown not in compute_noshutdown_list:
                compute_shutdown_list_result.append(compute_shutdown)
        compute_noshutdown_list.clear()
        response_body = {"virtual_migration_list": movement_list_result, "compute_shutdown_list": compute_shutdown_list_result}
        '''
        movement_list_result = []
        for movement_virtual in hot_movement_list:
            if movement_virtual["status"] == "ACTIVE":
                movement_list_result.append(movement_virtual)
        #response_body = {"virtual_migration_list": movement_list_result, "compute_shutdown_list": compute_shutdown_list}
        response_body = {"virtual_migration_list":movement_list_result}
        print response_body
        for movement_virtual in movement_list_result:
            #开始迁移该虚拟机，并修改虚拟机状态。
            movement_virtual["status"] = "migrating"
            try:
                migration.manual_migration(movement_virtual["id"], movement_virtual["destination"])
            except(urllib2.HTTPError):
                movemetn_virtual["status"] = "failed"
                continue
            #虚拟机迁移完毕，更改虚拟机状态。
            movement_virtual["status"] = "completed"
                
        print response_body
        #将信号量内计数器加1。
        semaphore.release()
        #lock.release()
        time.sleep(30)

def application (environ, start_response):
    """http请求处理函数。
    
    处理http请求，返回需要迁移的虚拟机和要关闭的物理机。

    参数：
        environ: http请求信息。 
        start_response: 回复的头部信息。

    返回值：
        返回http回复的body信息，json格式。
    """
    global semaphore
    global lock
    global response_body
    global movement_list_result
    global compute_shutdown_list_result
    print environ["QUERY_STRING"]
    if environ["QUERY_STRING"] != '':
        order = environ["QUERY_STRING"]
        action = order[5:]
        if action == "on":
            #当信号量内计数器大于0时，将计数器减1，返回True；当信号量内计数器等于0时，返回false。
            #防止自动迁移在开启状态时，又按下开启按键，导致程序错误。
            semaphore.acquire(blocking=False)    
            #将信号量内计数器加1，唤醒自动迁移算法线程。
            semaphore.release()
            response_body_http = "on"
        elif action =="off":
            #首先避免当自动热迁移处于关闭状态，又按下关闭按键，导致该线程锁死。
            #其次，避免当收到关闭消息时，自动热迁移线程正在运行（该种情况非常小，因为自动热迁移线程
            #每运行一次，要休眠30秒），所以延迟0.5秒，在将信号量的计数值减1（自动热迁移线程计算完之
            #后会将信号量计数值加1，然后进入休眠状态）
            if not semaphore.acquire(blocking=False):
                time.sleep(0.5)
                semaphore.acquire(blocking=False)
            response_body_http = "off"
        else:
            response_body_http = "ERROR"
    else:
        #lock.acquire() 
        response_body_http = json.dumps(response_body)
        #movement_list_result = []
        #compute_shutdown_list_result = []
        #response_body.clear()
        #lock.release()

    status = '200 OK'
    response_headers = [
        ('Content-Type', 'text/json'),
        ('Content-Length', str(len(response_body_http)))
    ]
    start_response(status, response_headers)
 
    return response_body_http

def monitor():
    """http服务端监听函数。
    
    监听http请求，并且调用application函数处理请求。

    参数：
        无

    返回值：
        无
    """
    httpd = make_server('192.168.100.4', 419, application)
    httpd.serve_forever()

#创建自动迁移算法线程 
algorithm_thread = threading.Thread(target=dynamic_migration_algorithm)
#创建http监听线程
monitor_thread = threading.Thread(target=monitor)
#开始自动迁移算法线程
algorithm_thread.start()
#开始http监听线程
monitor_thread.start()

